import Food from "./Food";
import ScorePanel from "./scorePanel";
import Snake from "./Snake";

// 游戏控制器，控制其他所有的类
class GameControl {
    // 定义三个属性，蛇、食物、计分盘
    snake: Snake;
    food: Food;
    scorePanel: ScorePanel;
    //创建一个属性来存储蛇的移动方向（也就是按键的方向）
    direction: string = '';
    // 创建一个属性来记录游戏是否结束
    isLive = true;

    constructor() {
        this.snake = new Snake();
        this.food = new Food();
        this.scorePanel = new ScorePanel(10,2);
        this.init();
    }

    // 游戏初始化方法，调用后游戏即开始
    init() {
        // 绑定按键按下的事件
        document.addEventListener('keydown', this.keyDownHandler.bind(this));
        // 调用run方法，使蛇移动
        this.run();
    }
    // 创建键盘按下的响应函数
    keyDownHandler(event: KeyboardEvent) {
        //console.log(event.key);//ArrowUp ArrowDown ArrowLeft ArrowRight Up Down Left Right
        // 需要检查event.key的值是否合法（按下的键是否是上下左右四个键）
        this.direction = event.key;
    }

    // 创建一个控制蛇移动的方法
    run() {
        // 根据方向(this.direction)来使蛇的位置改变
        /* 
            向上 top减少；向下 top增加；向左 left减少；向右 left增加
        */
        // 获取蛇现在的坐标
        let x = this.snake.X;
        let y = this.snake.Y;
        // 根据按键方向来修改蛇的坐标值，但是并没有应用到蛇的身上
        switch (this.direction) {
            case "ArrowUp":
            case "Up":
                y -= 10;
                break;
            case "ArrowDown":
            case "Down":
                y += 10;
                break;
            case "ArrowLeft":
            case "Left":
                x -= 10;
                break;
            case "ArrowRight":
            case "Right":
                x += 10;
                break;
        }

        // 蛇是否吃到食物
        this.checkEat(x, y);

        try {
            // 设置蛇的坐标值
            this.snake.X = x;
            this.snake.Y = y;
        } catch (e: any) {
            alert(e.message + '! GAME OVER!');
            this.isLive = false;//游戏结束
        }

        // 当this.isLive为true时就开启一个定时调用
        this.isLive && setTimeout(this.run.bind(this), 300 - (this.scorePanel.level - 1) * 30);//一开始每隔300ms就移动一次，等级提高后速度就会变快
    }

    // 检查蛇是否吃到食物的方法
    checkEat(snakeX: number, snakeY: number) {
        if (snakeX === this.food.X && snakeY === this.food.Y) {
            // console.log('吃到食物了');
            // 吃到食物后食物的位置要重置；分数要增加；蛇要增加一节
            this.food.change();
            this.scorePanel.addScore();
            this.snake.addBody();
        }
    }
}

export default GameControl;